package org.ghost.parallel.demo;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * 读与读之间不阻塞，针对读为大部分场景的有很大优势
 */
public class ReadWriteLockTest {
    private final Logger logger = LoggerFactory.getLogger(ReadWriteLockTest.class);

    private static ReentrantLock normalLock = new ReentrantLock(true);
    private static ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock(true);
    private static ReentrantReadWriteLock.ReadLock readLock = readWriteLock.readLock();
    private static ReentrantReadWriteLock.WriteLock writeLock = readWriteLock.writeLock();

    private int sum = 0;

    public Object getSumRead() {
        try {
            if (readLock.tryLock(1L, TimeUnit.MINUTES)) {
                Thread.sleep(100L);
                return sum;
            }
        } catch (InterruptedException e) {
            logger.error("*****getSum出现异常,sum={},{}", sum, e);
        } finally {
            readLock.unlock();
        }
        return null;
    }

    public void setSumWrite(int i) {
        try {
            if (writeLock.tryLock(1L, TimeUnit.MINUTES)) {
                Thread.sleep(100L);
                sum += i;
                logger.info("*****setSumWrite之后sum={}", sum);
            }
        } catch (InterruptedException e) {
            logger.error("*****setSum出现异常,sum={},{}", sum, e);
        } finally {
            if (writeLock.isHeldByCurrentThread()) {
                writeLock.unlock();
            }
        }
    }

    public Object getSum() {
        try {
            if (normalLock.tryLock(1L, TimeUnit.MINUTES)) {
                Thread.sleep(100L);
                return sum;
            }
        } catch (InterruptedException e) {
            logger.error("*****getSum出现异常,sum={},{}", sum, e);
        } finally {
            if (normalLock.isHeldByCurrentThread()) {
                normalLock.unlock();
            }
        }
        return null;
    }

    public void setSum(int i) {
        try {
            if (normalLock.tryLock(1L, TimeUnit.MINUTES)) {
                Thread.sleep(100L);
                sum += i;
                logger.info("*****setSum之后sum={}", sum);
            }
        } catch (InterruptedException e) {
            logger.error("*****setSum出现异常,sum={},{}", sum, e);
        } finally {
            if (normalLock.isHeldByCurrentThread()) {
                normalLock.unlock();
            }
        }
    }


}
